import BaseLabel_blxf from "../Base/BaseLabel";
import GameData_blxf from "../GameData/GameData";
import { CsvManager_blxf } from "../Manager/CsvManager";
import { EnumManager_blxf } from "../Manager/EnumManager";
import PageManager_blxf from "../Manager/PageManager";
import { PlatformManager_blxf } from "../Manager/PlatformManager";
import { ConfigModule_blxf } from "./ConfigModule";
import { LoadModule_blxf } from "./LoadModule";
import { NumModule_blxf } from "./NumModule";
import PublicModule_blxf from "./PublicModule";



const {ccclass, property} = cc._decorator;

/** 游戏工具模块 */
@ccclass
export class UtilsModule_blxf {

    private constructor () {};

    private static _UtilsModule_blxf: UtilsModule_blxf = new UtilsModule_blxf();

    public static get instance () {
        return this._UtilsModule_blxf;
    }

    /**
     * 系统提示
     * @param tipsMsg 提示语 
     */
    static onTips_blxf ( tipsMsg: string ) {
        PageManager_blxf.instance.loadComonTipsPanel_blxf({ tipsMsg });
    }

    /**
     * 设置文本内容
     * @param textNode 文本节点
     * @param text 文本内容
     * @param width 描边宽度
     */
    static setText_blxf ( textNode: cc.Node, text: string, width: number = 0 ) {
        if ( !textNode || !cc.isValid( textNode ) ) return;
        
        let _baseLabelThis: BaseLabel_blxf = textNode.getComponent( BaseLabel_blxf );
        if ( !_baseLabelThis ) return;

        _baseLabelThis.setText_blxf( text, width );
    }

    /**
     * 设置配置文本
     * @param textNode 文本节点 
     * @param textId 配置id
     * @param width 描边宽度
     */
    static setConfigText_blxf ( textNode: cc.Node, textId: string, width: number = 0 ) {
        let _btnText: string = CsvManager_blxf.instance.getCfgText_blxf( textId );
        this.setText_blxf( textNode, _btnText, width );
    }

    /**
     * log日志
     * @param logText 文字
     * @param logLevel 等级（1: log、2: warn、3: error）
     */
    Log_blxf ( logText: any, logLevel: number = 1 ) {
        let { isDebug } = ConfigModule_blxf;
        if ( !isDebug ) return;

        switch ( logLevel ) {
            case 1 : cc.log( logText );      break;
            case 2 : cc.warn( logText );     break;
            case 3 : cc.error( logText );    break;
            default: console.log( logText ); break;
        }
    };

    /** 检测是否是繁体 */
    isTraditionalChinese_blxf (){
        // console.log('cc.sys.languageCode >>', cc.sys.language, cc.sys.languageCode);
        // return true   // todo test

        if (cc.sys.language != cc.sys.LANGUAGE_CHINESE){
            return false;
        }

        let code = cc.sys.languageCode || '';

        // 包含hant的就是繁体
        if ( code.indexOf('hant') != -1 ){ 
            return true;
        }

        // 包含hans的就是简体
        if ( code.indexOf('hans') != -1 ){ 
            return false;
        }

        if ( 
            code.indexOf('zh-hk') != -1
            || code.indexOf('zh-tw') != -1
            || code.indexOf('zh-mo') != -1
            || code.indexOf('zh_hk') != -1
            || code.indexOf('zh_tw') != -1
            || code.indexOf('zh_mo') != -1
        ){
            return true;
        }

        return false;
    }

    /** 节点适配 */
    setNodeSize_blxf ( node: cc.Node ) {
        let { winSizeW, winSizeH, scaleRatio, gameW, gameH } = ConfigModule_blxf.instance;
        node.width = winSizeW / scaleRatio;
        node.height = winSizeH /*/ scaleRatio*/;
    }

    /** 加载分包 */
    loadBundPanel_blxf ( bundleType: number, cb: any = ()=>{} ) {
        let _bundleIds: number[];
        switch ( bundleType ) {
            case 1 : _bundleIds = [ 1, 3 ]; break;
            case 2 : _bundleIds = [ 2, 3 ]; break;
            case 3 : _bundleIds = [ 3 ]; break;
        }
        if ( !_bundleIds ) return cb && cb();

        let _isLoad: boolean = PublicModule_blxf.onCheckBundleIds( _bundleIds );
        if ( _isLoad ) return cb && cb();

        PublicModule_blxf.addBundleIds( _bundleIds );
        // PageManager_blxf.instance.loadBundPanel_blxf( { bundleId: bundleType, cb } );
    }

    /**
     * 获取文本类型
     * @returns 返回文本类型
     */
    getTextType_blxf () {
        let _textType: string = 'CN';

        let { languageType } = ConfigModule_blxf.instance;
        switch ( languageType ) {
            case 2 : _textType = 'Hant'; break;
            default: _textType = 'CN';
        }

        return _textType;
    }

    /**
     * 设置文字
     * @param labelNode 文字节点
     * @param text 文字
     */
    setText_blxf ( labelNode: cc.Node, text: string ) {
        labelNode.getComponent(BaseLabel_blxf).setText_blxf( text );
    }

    /**
     * 设置点击状态
     * @param self this对象
     * @param timer 状态解除时间
     */
    setClick_blxf ( self: any, timer: number = 0.5 ) {
        self._isClick = true;
        self.scheduleOnce(()=>{
            self._isClick = false;
        }, timer);
    }

    /**
     * 加载icon图片
     * @param imgSpr 图片
     * @param iconType 图标类型 1金币、2元宝、9视频、10分享
     */
    loadIconImg_blxf ( iconType: number, imgSpr: cc.Sprite, imgBox: cc.Node = null ) {
        let _atlasName: string, _imgName: string;

        switch ( Number(iconType) ) {
            case 1 : _atlasName = 'ZYWF'; _imgName = 'Elt_Jinbi'; break;
            case 2 : _atlasName = 'ZYWF'; _imgName = 'Elt_Yuanbao'; break;
            case 9 : _atlasName = 'ZYWF'; _imgName = 'Elt_Shipin'; break;
            case 10: _atlasName = 'ZYWF'; _imgName = 'TB_fenxiang'; break;
            case 11: _atlasName = 'ZYWF'; _imgName = 'TB_fenxiang2'; break;
            default: this.Log_blxf(`loadIconImg_blxf 参数错误 iconType => ${iconType}`); break;
        }

        if ( !_imgName ) return;

        let _options: object = {
            path : _atlasName,
            imgName : _imgName,
            imgSpr, imgBox
        }
        LoadModule_blxf.instance.LoadImg_blxf( _options );
    }

    /**
     * 根据图片盒子大小适配图片
     * @param imgSprite 图片纹理
     * @param imgBox 图片盒子
     * @param isSpecial 是否不超过原比例
     * @returns 
     */
    setSpriteSizeInNodes_blxf ( imgSprite: cc.Sprite, imgBox: cc.Node, isSpecial: boolean = false ) {
        if ( !imgSprite || !imgSprite.spriteFrame || !imgBox || !cc.isValid(imgBox) ) {
            return this.Log_blxf(`setSpriteSizeInNodes 参数错误 >> imgSprite = ${imgSprite}, imgBox = ${imgBox}`, 2);
        }
        
        let _spriteRect: any = imgSprite.spriteFrame['_rect'];
        if ( !_spriteRect ) return;

        let _spriteW: number = _spriteRect.width;
        let _spriteH: number = _spriteRect.height;

        let _widthScale: number = imgBox.width / _spriteW;
        let _heightScale: number = imgBox.height / _spriteH;

        let _adapterScale = Math.min( _widthScale, _heightScale );
        if (isSpecial && _adapterScale > 1) _adapterScale = 1;

        // 改变原版大小的比例
        imgSprite.node.width = _adapterScale * _spriteW;
        imgSprite.node.height = _adapterScale * _spriteH;
    };

    /** 复制数据 */
    getCopyData_blxf ( data: any ) {
        return JSON.parse(JSON.stringify( data ));
    };

    /**
     * 获取绝对坐标
     * @param node 节点
     * @param pos 节点坐标
     * @returns 绝对坐标
     */
    getCanvasPos_blxf ( node: cc.Node, pos: cc.Vec3 = null ) {
        if ( !node || !cc.isValid(node) || !node.parent ) return cc.v2();

        if ( !pos ) pos = node.position;

        let _parentNode: cc.Node = node.parent;
        if ( !_parentNode || !cc.isValid(_parentNode) ) return pos;

        let _isCanvas: boolean = _parentNode.name == 'Canvas';
        if ( _isCanvas ) return pos;

        let _parentPos: cc.Vec3 = _parentNode.position;
        pos = pos.add(_parentPos);
        pos.x *= _parentNode.scaleX;
        pos.y *= _parentNode.scaleY;

        return this.getCanvasPos_blxf( _parentNode, pos );
    }


    /**
     * 创建Spine动画
     * @param spineId 动画id
     * @param parentNode 父节点
     * @param cb 创建完成回调
     */
    createSpine_blxf ( spineId: string, parentNode: cc.Node, cb: any, animationName: string = null, basePos: cc.Vec3 = cc.v3() ) {
        let _spineData: any = CsvManager_blxf.instance.getSpineDataById_blxf( spineId );
        if ( !_spineData ) return this.Log_blxf(`创建Spine动画失败: ${spineId}`);

        let _isHant = UtilsModule_blxf.instance.isTraditionalChinese_blxf();
        let { BundleName, SpineId, SpineName, FileName, FileName_Hant, DirName, DefaultName, Loop, IsAlpha, PosX, PosY, ZIndex } = _spineData;
        PosX = Number(PosX || 0), PosY = Number(PosY || 0);
        if ( _isHant && FileName_Hant ) FileName = FileName_Hant;

        let zIndex: number = Number( ZIndex );
        let position: cc.Vec3 = cc.v3( PosX, PosY ).add( basePos );
        let spinePath: string = DirName ? `${DirName}/${FileName}` : `${FileName}`;
        animationName = animationName || DefaultName;

        // 创建动画节点
        let _spineNode: cc.Node = new cc.Node();
        _spineNode.addComponent( sp.Skeleton );
        _spineNode.name = SpineName;

        // 添加动画节点
        let _options: object = {
            prefabNode: _spineNode, parentNode, position, zIndex
        }
        let _spineNodeItem: cc.Node = LoadModule_blxf.instance.LoadNode_blxf( _options );

        // 加载动画数据
        let _spineSkeleton: sp.Skeleton = _spineNodeItem.getComponent(sp.Skeleton);
        LoadModule_blxf.instance.LoadSpine_blxf( BundleName, spinePath, _spineSkeleton, ()=>{

            // 播放默认动画
            let skinName: string;
            let { SPINE_ALL_SHOP_GUEST } = EnumManager_blxf.gameSpineType;
            if ( spineId == SPINE_ALL_SHOP_GUEST ) {
                skinName = _isHant ? 'ft' : 'jt';
            }

            let isLoop: boolean = Loop == 1, isAlpha: boolean = IsAlpha == 1;
            this.palyAnimation_blxf( _spineSkeleton, { skinName, animationName, isLoop, isAlpha } );

            // 播放完自动销毁
            let _duration: number = NumModule_blxf.instance.onAnimationTime_blxf( _spineSkeleton, animationName );
            !isLoop && setTimeout(()=>{
                if ( !_spineSkeleton.node || !cc.isValid(_spineSkeleton.node) ) return;
                _spineSkeleton.node.destroy();
            }, _duration * 1000 - 17);

            cb && cb( _spineSkeleton, _duration );
        });

        // 渐现（游戏主页动画）
        let _isMain: boolean = DirName == 'Main';
        _isMain && this.onNodeFadeIn_blxf( _spineNodeItem );
    }

    /**
     * 播放动画
     * @param skeleton spine动画
     * @param options { 动画skeleton: sp.Skeleton, 皮肤名skinName: string, 动画名animationName: string, 是否循环isLoop: boolean = true, 播放倍速timeScale: number = 1 }
     */
    palyAnimation_blxf ( skeleton: sp.Skeleton, options: any ) {
        let { skinName, animationName, isLoop, timeScale, isAlpha } = options;

        isLoop = isLoop || true;
        timeScale = timeScale || 1;
        skinName = skinName || 'default';
        animationName = animationName || 'animation';

        try {
            skeleton.setSkin(skinName)
            skeleton.timeScale = timeScale;
            skeleton.setAnimation( 0, animationName, isLoop );
            skeleton.premultipliedAlpha = isAlpha;
        } catch ( e ) {
            // if ( skeleton && skeleton['_name']) console.log('skeleton >>', skeleton['_name'], options);
            // console.error('e.stack >>', e.stack);
        }
    }

    /**
     * 渐显
     * @param node 节点渐现 
     * @param t 时间
     */
    onNodeFadeIn_blxf ( node: cc.Node, t: number = 1.5 ) {
        node.opacity = 0;
        cc.tween( node ).to(t, { opacity: 255 }, cc.easeSineInOut()).start();
    }

    /**
     * 复制节点，飞向终点坐标
     * @param copyNode 复制节点
     * @param endPos 终点坐标
     * @param scaleRatio 缩放系数
     * @param cb 回调函数
     */
    onCopyNode_blxf ( copyNode: cc.Node, endPos: cc.Vec3, scaleRatio: number, cb: any = ()=>{} ) {
        let _nodePos: cc.Vec2 = this.getCanvasPos_blxf( copyNode );
        
        let _copyNode: cc.Node = LoadModule_blxf.instance.LoadNode_blxf({
            prefabNode: copyNode, position: _nodePos, zIndex: 2999
        })

        this.onMoveTargetAnimation_blxf( _copyNode, endPos, scaleRatio, cb );
    }

    /**
     * 设置节点层级
     * @param node 节点
     * @param addZIndex 额外附近层级 
     */
    setNodeZIndex_blxf ( node: cc.Node, addZIndex: number = 0 ) {
        let { winSizeH } = ConfigModule_blxf.instance;
        let _zIndex: number = winSizeH / 2 - node.y;
        node.zIndex = _zIndex + addZIndex;
    }
    
    /**
     * 移动至目标动画
     * @param moveNode 移动节点
     * @param endPos 终点坐标
     * @param scaleRatio 缩放比例
     * @param cb 回调函数
     */
    onMoveTargetAnimation_blxf ( moveNode: cc.Node, endPos: cc.Vec3, scaleRatio: number, cb: any ) {
        let scale = moveNode.scale * scaleRatio;
        let t = ( Math.abs(moveNode.x - endPos.x) + Math.abs(moveNode.y - endPos.y) ) / 1000;

        cc.tween(moveNode)
        .to(t, { x: endPos.x, y: endPos.y, scale, opacity: 180 }, cc.easeSineInOut())
        .call( ()=>{
            cb && cb();
            moveNode.destroy();

            PublicModule_blxf.isMoveAnimation = false;
        })
        .start();
    }

    // 晃动动画
    onIconTween ( self: any, isTween: boolean, iconNode: cc.Node, tweenName: string ) {
        if ( !isTween ) {
            self[tweenName] && self[tweenName].stop();
            self[tweenName] = null;
            return iconNode.angle = 0;
        }

        if ( self[tweenName] ) return;

        let _t1 = 0.1, _t2 = 2 * _t1, _angle = 8, _delayTime = 2;
        let _tween = cc.tween( iconNode )
            .delay( _delayTime )
            .by(_t1, { angle: _angle })
            .by(_t2, { angle: -_angle * 2 })
            .by(_t1, { angle: _angle })
            .by(_t1, { angle: _angle })
            .by(_t2, { angle: -_angle * 2 })
            .by(_t1, { angle: _angle })
        
        self[tweenName] = cc.tween( iconNode ).repeatForever( _tween ).start();
    }

    /** 检测是否是同一天 */
    static onCheckNowDay_blxf ( checkTime: number ) {
        if ( !checkTime ) return false;

        let _nowTimeStr: string = NumModule_blxf.instance.getTimeStr_blxf();
        let _userTimeStr: string = NumModule_blxf.instance.getTimeStr_blxf( checkTime );
        // cc.log('checkNowDay nowStr = timeStr =>', _nowTimeStr, _userTimeStr);
        return _userTimeStr == _nowTimeStr;
    }

    /** 检测是否是新用户 */
    static onCheckNewUser_blxf () {
        let _isNewUser: boolean;

        let _userRegisterTime: number = GameData_blxf.instance.getUserRegisterTime_blxf();
        let _nowTimeStr: string = NumModule_blxf.instance.getTimeStr_blxf();
        let _userTimeStr: string = NumModule_blxf.instance.getTimeStr_blxf( _userRegisterTime );
        
        _isNewUser = !_userRegisterTime || _nowTimeStr == _userTimeStr;

        return _isNewUser;
    }

    /**
     * 检测是否上报
     * @param eventId 事件id
     * @returns 返回是否上报 
     */
    static onCheckIsReport_blxf ( eventId: number ) {
        let _reportEventIdList: number[] = GameData_blxf.instance.getReportEventIdList_blxf();
        let _isReport: boolean = _reportEventIdList.includes( eventId );

        return _isReport;
    }

    /**
     * 上报自定义事件
     * @param eventId 事件id
     */
    static onReportEvent_blxf ( eventType: number, eventId: number, isPass: boolean = false, eventOptions: any = {} ) {
        let _isNewUser: boolean = this.onCheckNewUser_blxf();
        if ( eventType == 1 && !_isNewUser ) return;

        let _isReport: boolean = this.onCheckIsReport_blxf( eventId );
        if ( eventType == 1 && _isReport ) return;

        // if ( isPass ) {
        //     let _passNum: number = GameData_blxf.instance.getBigPassNum_blxf();
        //     eventOptions = { "level": `${_passNum}` }

        //     // if ( _passNum > 100 ) return;
        // }

        PlatformManager_blxf.instance.onReportEvent_blxf( eventId, eventOptions, eventType );
    }

    /**
     * 分享
     * @param shareId 分享id: 1老板别走 或 空间不足、2临时摊位、3过关弹窗、11炫耀一下、12摇人帮忙、13我想吃、14我会做
     */
    static onShareMessage ( shareId: number, title: string = null ) {
        // 直接分享成功
        if ( cc.sys.isBrowser ) {
            return setTimeout(()=>{
                cc.game.emit(`onShareOK${ shareId }_blxf`);
            }, 20)
        }

        let _isApp: boolean = ConfigModule_blxf.isAppPlatform_blxf();
        if ( _isApp ) return this.onAppShare_blxf();

        let { shareCfgInfo } = ConfigModule_blxf;
        let _shareData: any = shareCfgInfo[`cfg${ shareId }`] || {};
        _shareData[ 'shareId' ] = shareId;
        if ( title ) {
            _shareData[ 'title' ] = title;
            _shareData[ 'imageUrl' ] = this.onTempFilePath( shareId );
        }
        PlatformManager_blxf.instance.onShareAppMessage_blxf( _shareData );
    }

    /**
     * 截取特定区域
     * @param shareId 分享id 
     * @returns 返回截图url
     */
    static onTempFilePath ( shareId: number ) {
        let _data: object = {
            11 : {
                yRatio: 0.16,
                heightRatio: 0.4
            },
            12 : {
                yRatio: 0.16,
                heightRatio: 0.4
            },
            13 : {
                yRatio: 0.5,
                heightRatio: 0.5
            },
            14 : {
                yRatio: 0.5,
                heightRatio: 0.5
            }
        }
        let { yRatio, heightRatio } = _data[ shareId ];

        let _canvas = window['canvas'];
        let _w: number = _canvas.width, _h: number = _canvas.height;
        let tempFilePath = _canvas.toTempFilePathSync({
            x: 0,
            y: _h * yRatio,
            width: _w,
            height: _h * heightRatio,
            destWidth: 500,
            destHeight: 400
        })
        return tempFilePath;
    }

    /** APP分享 */
    static onAppShare_blxf ( cb: any = ()=>{} ) {
        let { appShareImgPath, appShareText, iosDownloadUrl, androidDownloadUrl } = ConfigModule_blxf;
        let _isIos: boolean = ConfigModule_blxf.isIosPlatform_blxf();
        let _shareUrl = _isIos ? iosDownloadUrl : androidDownloadUrl;

        LoadModule_blxf.instance.LoadImg_blxf({
            isImg : true,
            path  : appShareImgPath, 
            cb    : ( spriteFrame: cc.SpriteFrame ) =>{
                if ( !spriteFrame ) return;
                let _nativeUrl: string = spriteFrame['_texture'].nativeUrl;
                PlatformManager_blxf.instance.onShare_blxf({
                    shareTitle : '',
                    shareText  : appShareText, 
                    imagePath  : _nativeUrl,
                    shareUrl   : _shareUrl,
                    cb         : (res) => {
                        if (res == true) {
                            cb && cb(res);
                        }
                    }
                })
            }
        })
    }
    

    /**
     * 获取通用数据
     * @param index 小关下标 
     * @returns 通用数据
     */
    onCommonShopData_blxf ( index: number ) {
        // {"ShopId":"200","ShopName":"紫苏","AtlasName":"WuPin","ImgName":"wp_200","IsUnlock":"","NeedShopNum":"200","NewGuestId":""}
        let _commonList = [
            {"IsCommon":"1","RewardType":"1","RewardNum": "100","ShopName":"金币","AtlasName":"ZYWF","ImgName":"Elt_Jinbi","IsUnlock":"","NeedShopNum":"200","NewGuestId":""},
            {"IsCommon":"1","RewardType":"1","RewardNum": "100","ShopName":"金币","AtlasName":"ZYWF","ImgName":"Elt_Jinbi","IsUnlock":"","NeedShopNum":"200","NewGuestId":""},
            {"IsCommon":"1","RewardType":"2","RewardNum": "100","ShopName":"元宝","AtlasName":"ZYWF","ImgName":"Elt_Yuanbao","IsUnlock":"","NeedShopNum":"200","NewGuestId":""}
        ]

        let _commonShopData: any = _commonList[ index ];
        // _commonShopData['NeedShopNum'] = 20;     // todo test

        // 财富：50、100、150，金币：1000、1500、2000
        let _bigPassNum: number = GameData_blxf.instance.getBigPassNum_blxf();
        let _diamondNum: number = 50 * ( _bigPassNum - 66 );
        let _goldNum: number = 1000 * ( _bigPassNum - 67 ) + 500 * index;
        _commonShopData['RewardNum'] = index == 2 ? _diamondNum : _goldNum;
        UtilsModule_blxf.instance.Log_blxf([ '_commonShopData index >>', index, _commonShopData ]);

        return _commonShopData;
    }

    /** 获取视频金币数 */
    static onVideoGoldNum_blxf () {
        let { videoGoldNumStr } = ConfigModule_blxf;
        let _bigPassNum: number = GameData_blxf.instance.getBigPassNum_blxf();
        let _videoGoldNum: number = NumModule_blxf.instance.onEval_blxf( videoGoldNumStr, 'LV', _bigPassNum );

        return _videoGoldNum;
    }

    /** 是否双倍收益时间 */
    static isDoubleRewardTime_blxf () {
        let _doubleRewardTime: number = GameData_blxf.instance.getAutoDoubleRewardTime_blxf();
        return _doubleRewardTime > 0;
    }

    /** 是否双倍速度时间 */
    static isDoubleSpeedTime_blxf () {
        let _doubleSpeedTime : number = GameData_blxf.instance.getAutoDoubleSpeedTime_blxf();
        return _doubleSpeedTime > 0;
    }

    /**
     * 记录滑动列表位列
     * @param sv 滑动组件
     * @param index 记录下标
     */
    onRecordSvPos_blxf ( sv: cc.ScrollView, index: number ) {
        let _scrollOffset: cc.Vec2 = sv.getScrollOffset();
        PublicModule_blxf.scrollOffsetYs = PublicModule_blxf.scrollOffsetYs || [];
        PublicModule_blxf.scrollOffsetYs[ index ] = _scrollOffset.y;
    }

    /** 兼容解锁商品 */
    onCheckUnlockShopId_blxf () {
        let { CSV_SHOP } = EnumManager_blxf.instance.getGameCsvType();
        let _cfgShopData: any[] = CsvManager_blxf.instance.getCsvDataByName_blxf( CSV_SHOP );
        let _shopList: any[] = GameData_blxf.instance.getShopList_blxf();
        let _guestList: any[] = GameData_blxf.instance.getGuestList_blxf();
        let _passNum = GameData_blxf.instance.getPassNum_blxf();
        _cfgShopData.forEach( cfgItem =>{
            let { ShopId, NewGuestId } = cfgItem;
            if ( _passNum <= Number(ShopId) ) return;

            let _guestData = _guestList.find( item => item.guestId == NewGuestId );
            if ( !_guestData ) {
                GameData_blxf.instance.unlockGuest_blxf( Number(NewGuestId) );
                GameData_blxf.instance.unlockGuestId_blxf( Number(NewGuestId) );
            }

            let _shopData = _shopList.find( item => item.shopId == ShopId );
            if ( !!_shopData ) return;

            GameData_blxf.instance.unlockShop_blxf( Number(ShopId) );
        })
    }
    
    /** 兼容解锁装饰客人 */
    onCheckUnlockDecorationGuest_blxf () {
        let _decorationList: any[] = CsvManager_blxf.instance.getDecorationData_blxf();
        _decorationList.forEach( item =>{
            let { isUnlock, BuildId, LikeGuestId } = item;
            if ( !isUnlock ) return;
            if ( !LikeGuestId ) return;

            let _guestId = Number( LikeGuestId );
            let _isUnlockGuest: boolean = GameData_blxf.instance.onIsUnlockGuest_blxf( _guestId );
            if ( _isUnlockGuest ) return;

            GameData_blxf.instance.unlockGuest_blxf( _guestId );
            GameData_blxf.instance.unlockGuestId_blxf( _guestId );
        })
    }

    // 重置增益数据
    onInitBuffData_blxf ( isVideo: boolean = false ) {
        PublicModule_blxf.onInitBuffData_blxf();
        PublicModule_blxf.onUpdateVideoStartTime_blxf();

        isVideo && PublicModule_blxf.onCheckJengaVideoNum_blxf();
    }

    onIsPropVideo_blxf ( propId: number ) {
        let _useNum: any = GameData_blxf.instance.getPropNumList_blxf( propId );
        let _isVideo: boolean = _useNum == 0 && PublicModule_blxf.onCheckIsOpenProp_blxf( propId );
        return _isVideo;
    }

    onIsPropNum_blxf ( propId: number, isUse: boolean = true ) {
        let _isUse: boolean = false;
        switch ( Number( propId) ) {
            case 1 : _isUse = PublicModule_blxf.isPropRemove; break;
            case 2 : _isUse = PublicModule_blxf.isPropExchange; break;
        }
        if ( !isUse ) _isUse = true;

        let _useNum: any = GameData_blxf.instance.getPropNumList_blxf( propId );
        let _isNum: boolean = _useNum > 0;

        return _isNum && _isUse;
    }

    /** 是否可使用交换道具功能 */
    onIsPropExchange_blxf () {
        let _exchangePropId: number = 2;
        let _propNum: any = GameData_blxf.instance.getPropNumList_blxf( _exchangePropId );
        let _isUseExchange: boolean = _propNum > 0 && PublicModule_blxf.isPropUsePanel;
        return _isUseExchange;
    }

    /** 检测是否解锁菜品 */
    onCheckIsUnlockFoodId_blxf ( foodId: number ) {
        let _isUnlock: boolean;

        let _foodIdList: number[] = GameData_blxf.instance.getFoodIdList_blxf();
        _isUnlock = _foodIdList.includes( foodId );

        return _isUnlock;
    }

    onCheckUnlockFoodIcon () {
        let _foodIdList: number[] = GameData_blxf.instance.getFoodIdList_blxf();
        let _isUnlock: boolean = _foodIdList.length > 0;
        return _isUnlock;
    }

    /**
     * 检测收集粮票信息
     * @param type 收集类型
     * @returns 返回收集信息
     */
    onCheckCollectPaperInfo ( type: number ) {
        let _receivePaperDataList: any[] = [];
        let _okNum: number, _maxNum: number;
        let _receivePaperType, _receivePaperNum: number = 0;

        let _idList: number[] = [];
        switch ( type ) {
            case 1 : _idList = GameData_blxf.instance.getFoodIdList_blxf(); break;
            case 2 : _idList = GameData_blxf.instance.getShopIdList_blxf(); break;
            case 3 : _idList = GameData_blxf.instance.getGuestIdList_blxf(); break;
        }
        _okNum = _idList.length;

        let _collectPaperList: number[] = GameData_blxf.instance.getCollectPaperList_blxf();
        let _paperDataList: any[] = CsvManager_blxf.instance.onPaperDataList_blxf( type );
        _paperDataList.sort((a, b) => a.Condition - b.Condition );

        _paperDataList.forEach( item =>{
            let { ID, Condition, RewardType, RewardNum } = item;
            
            let _isOk: boolean = _okNum - Condition >= 0;
            if ( !_isOk ) {
                if ( !_maxNum ) _maxNum = Number( Condition );
                return;
            }

            let _isCheck: boolean = _collectPaperList.includes( Number(ID) );
            if ( _isCheck ) return;

            _maxNum = Number( Condition );

            _receivePaperDataList.push( item );

            _receivePaperType = Number( RewardType );
            _receivePaperNum += Number( RewardNum );
        })

        let _info: any = {
            okNum: _okNum, 
            maxNum: _maxNum,
            receivePaperType: _receivePaperType,
            receivePaperNum: _receivePaperNum,
            receivePaperDataList: _receivePaperDataList
        }
        return _info;
    }

    /** 使用道具埋点 */
    static onUsePropReportEvent_blxf ( propId: number ) {
        let _propName: string;

        switch ( propId ) {
            case 1 : _propName = '消除道具'; break;
            case 2 : _propName = '换位道具'; break;
            case 3 : _propName = '刷新道具'; break;
        }

        _propName && UtilsModule_blxf.onReportEvent_blxf( 2, 201, false, { "tools": `${_propName}` });
    }
    
    /**
     * 获取数字颜色
     * @param colorId 颜色id 
     * @returns 返回颜色
     */
    onNumColor_blxf ( colorId: number ) {
        let _r: number = 0, _g: number= 0, _b: number= 0;
        switch ( colorId ) {
            case 1: _r = 126, _g =  50, _b =   0; break;
            case 2: _r = 124, _g =  47, _b =  47; break;
            case 3: _r = 171, _g =  93, _b =  17; break;
            case 4: _r = 219, _g = 222, _b = 255; break;
            case 5: _r =  74, _g =  98, _b = 142; break;
            case 6: _r =  72, _g =  44, _b = 103; break;
            case 7: _r =  55, _g = 105, _b =  46; break;
            case 8: _r = 175, _g =  43, _b =  80; break;
            case 9: _r =  86, _g = 140, _b =  21; break;
            case 10: _r = 67, _g = 164, _b = 144; break;
        }

        // _r = 0, _g = 0, _b = 0;
        // _r = 255, _g = 255, _b = 255;

        let _color: cc.Color = new cc.Color( _r, _g, _b, 255 );
        return _color;
    }

    /** 缩放动画 */
    onScaleAnimation_blxf ( node: cc.Node, updateScaleNum: number, cb: any = ()=>{} ) {
        let _oldScale: number = node.scale;
        let _scale: number = _oldScale + updateScaleNum;
        cc.tween( node ).to( 0.1, { scale: _scale } ).to( 0.1, { scale: _oldScale }).call(()=>{
            cb && cb();
        }).start();
    }

    /**
     * 获取埋点关卡上报数据
     * @param gameType 游戏类型 1：小摊贩、2：叠叠乐
     * @returns 
     */
    onReportEventData_blxf ( gameType: number ) {
        let _data = {};

        let _passNum1: number = GameData_blxf.instance.getPassNum_blxf();
        let _passNum2: number = GameData_blxf.instance.getJengaPassNum_blxf();

        let { basePassNum } = ConfigModule_blxf;
        let _n1: number = Math.ceil( ( _passNum1 - 1 ) / basePassNum );
        let _n2: number = ( _passNum1 - 1 ) % basePassNum;
        let _passStr: any = gameType == 1 ? `${_n1}_${_n2}` : _passNum2;

        _data[ `level_game${gameType}` ] = `${ _passStr }`;

        return _data;
    }

    /**
     * 第一次上报对应埋点事件
     * @param gameType 游戏类型 1：小摊贩、2：叠叠乐
     * @param eventId 事件id
     */
    onFristReportEvent_blxf ( gameType: number, eventId: number ) {
        let _isReport: boolean = UtilsModule_blxf.onCheckIsReport_blxf( eventId );
        if ( _isReport ) return;

        let _eventData: any = UtilsModule_blxf.instance.onReportEventData_blxf( gameType );
        UtilsModule_blxf.onReportEvent_blxf( 2, eventId, false, _eventData );

        GameData_blxf.instance.addReportEventId_blxf( eventId );
    }

    /** 视频埋点 */
    onVideoReportEvent_blxf () {
        let _gameType: number, _eventId1: number;
        switch ( PublicModule_blxf.gamePlayPageId ) {
            case 1 : _gameType = 1; _eventId1 = 301; break;
            case 4 : _gameType = 2; _eventId1 = 302; break;
        }
        if ( !_eventId1 ) return;

        // 第一次看视频
        UtilsModule_blxf.instance.onFristReportEvent_blxf( _gameType, _eventId1 );
    }

    /** 完成激励视频埋点 */
    onCompleteVideoReportEvent_blxf () {
        let _gameType: number, _eventId1: number;
        switch ( PublicModule_blxf.gamePlayPageId ) {
            case 1 : _gameType = 1; _eventId1 = 321; break;
            case 4 : _gameType = 2; _eventId1 = 322; break;
        }
        if ( !_eventId1 ) return;

        // 点击激励视频
        let _eventData: any = UtilsModule_blxf.instance.onReportEventData_blxf( _gameType );
        UtilsModule_blxf.onReportEvent_blxf( 2, _eventId1, false, _eventData );
    }

    /**
     * 观看视频广告成功
     * @param btnType btnType：1消除道具、2换位道具、3刷新道具、4解锁位置、5复活、6继续，看完广告并获得奖励后上报
     */
    static onBtnTypeReportEvent_blxf ( btnType: number ) {
        let _btnName: string;

        switch ( btnType ) {
            case 1 : _btnName = '消除道具'; break;
            case 2 : _btnName = '换位道具'; break;
            case 3 : _btnName = '刷新道具'; break;
            case 4 : _btnName = '解锁位置'; break;
            case 5 : _btnName = '复活'; break;
            case 6 : _btnName = '继续'; break;
        }

        _btnName && UtilsModule_blxf.onReportEvent_blxf( 2, 312, false, { "adv_game2": `${_btnName}`} );
    }

    /**
     * 检测是否有装饰可解锁
     * @param checkType 1自动售卖装饰、2房间内部装饰 
     */
    static onCheckNewBuildTips_blxf ( checkType: number ) {
        let _isNew: boolean;

        let _types: number[] = [];
        switch ( checkType ) {
            case 1 : _types = [ 1 ]; break;
            case 2 :
            case 3 : _types = [ 2, 3 ]; break;
        }

        _types.forEach( typeItem =>{
            if ( _isNew ) return;
            let _cfgList: any[] = CsvManager_blxf.instance.getDecorationDataList_blxf( checkType );
            _cfgList.forEach( item =>{
                if ( _isNew ) return;

                let { dataList } = item;
                if ( !dataList ) return;

                dataList.forEach( dataItem =>{
                    if ( _isNew ) return;
                    
                    let { isConsume } = dataItem;
                    _isNew = isConsume;
                })
            }) 
        })

        return _isNew;
    }

    /** 复制数据 */
    static onCopyList_blxf ( list: number[] ) {
        let _copyList: number[] = [];

        for ( let i = 0 ; i < list.length ; i++ ) {
            for ( let j = 0 ; j < 2 ; j++ ) {
                _copyList.push( list[ i ] );
            }
        }

        return _copyList;
    }

}
